package vip.liux.backend.application.serviceImpl.point;

import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.liux.application.dots.ListResultDto;
import vip.liux.application.dots.PagedResultDto;
import vip.liux.backend.application.service.point.*;
import vip.liux.backend.infrastructure.jpa.point.JpaPointsAccountRepository;
import vip.liux.contracts.models.point.PointsAccount;
import vip.liux.contracts.models.point.PointsAccountDomainService;
import vip.liux.contracts.shared.enums.point.PointRuleType;
import vip.liux.core.exception.BusinessException;

import java.util.List;
import java.util.Optional;

import static vip.liux.backend.infrastructure.constants.GlobalConstant.SNOWFLAKE;

@Service
@RequiredArgsConstructor
@Slf4j
public class PointsAccountServiceImpl implements PointsAccountService {

    private final PointsAccountDomainService userPointAccountDomainService;

    private final JpaPointsAccountRepository pointsAccountRepo;
    // 依赖循环, setter 注入
    @Setter
    @Lazy
    @Resource
    private PointsTransactionService pointsTransactionService;

    @Transactional(readOnly = true)
    @Override
    public PointsAccountDto getPointsOverview(Long userId) {
        PointsAccount account = userPointAccountDomainService.getAccount(userId);

        return PointsAccountDto.builder()
                .availablePoints(account.getAvailablePoints())
                .frozenPoints(account.getFrozenPoints())
                .expiredPoints(account.getExpiredPoints())
                .build();
    }

    @Override
    public ListResultDto<PointsAccountDto> getPointsList(List<Long> userIds) {
        return new ListResultDto<>(
                pointsAccountRepo.findByUserIdIn(userIds)
                        .stream().map(AutoMapperProfile.INSTANCE::toDto).toList()
        );
    }

    @Override
    public PagedResultDto<PointsAccountDto> queryAccount(PointsAccountQueryDto input) {
        return null;
    }

    /**
     * 后台调整积分
     */
    @Override
    public void adjustPoints(PointsAdjustDto dto) {
        if (dto.getType() == PointRuleType.ACQUIRE) {
            PointsRechargeDto rechargeDto = new PointsRechargeDto(dto.getUserId(), dto.getPoints(), String.valueOf(SNOWFLAKE.nextId()), Optional.ofNullable(dto.getReason()).orElse("后台调整积分" + dto.getPoints()));
            pointsTransactionService.rechargePoints(rechargeDto);
        } else if (dto.getType() == PointRuleType.CONSUME) {
            PointsConsumeDto rechargeDto = new PointsConsumeDto(dto.getUserId(), dto.getPoints(), String.valueOf(SNOWFLAKE.nextId()), Optional.ofNullable(dto.getReason()).orElse("后台调整积分" + dto.getPoints()));
            pointsTransactionService.consumePoints(rechargeDto);
        } else {
            throw new BusinessException("不支持的积分调整类型: " + dto.getType());
        }
    }
}